﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Demo
{
    public sealed class SimpleHybridLocked:IDisposable
    {
        private int m_waiters = 0;
        private AutoResetEvent m_waitLocked = new AutoResetEvent(false);

        public void Enter()
        {
            Console.WriteLine("enter线程：" +Thread.CurrentThread.ManagedThreadId.ToString());

            if (Interlocked.Increment(ref m_waiters) == 1){
                Console.WriteLine(" enter 直接返回 线程：" + Thread.CurrentThread.ManagedThreadId.ToString());
                return;  //锁可以自由竞争，直接返回
            }
            // 等待完后 这个线程就拿到了锁
            // 另一个线程拥有锁，发生了竞争关系，使这个线程等待。
            Console.WriteLine(" enter 等待 线程：" + Thread.CurrentThread.ManagedThreadId.ToString());
            m_waitLocked.WaitOne();// 性能影响
           
        }

        public void Leave()
        {
            Console.WriteLine("leave线程：" + Thread.CurrentThread.ManagedThreadId.ToString());
            if (Interlocked.Decrement(ref m_waiters) == 0) {
                Console.WriteLine(" Leave 没有其他 直接返回 线程：" + Thread.CurrentThread.ManagedThreadId.ToString());
                return;  //没有其他线程直接返回
            }
            Console.WriteLine(" Leave 有阻塞 线程：" + Thread.CurrentThread.ManagedThreadId.ToString());
            // 有其他线程阻塞，唤醒一个
            m_waitLocked.Set();// 产生大量性能问题
            Console.WriteLine(" Leave 有阻塞2 线程：" + Thread.CurrentThread.ManagedThreadId.ToString());
        }



        public void Dispose()
        {
            m_waitLocked.Dispose();
        }
    }
}
